#include "drvs.h"
#include "regs.h"
#include "micphone.h"
#include "adpcm.h"
#include "string.h"
#include "sadc.h"
#include "b6x.h"
#include "bledef.h"

#include "app.h"
#include "prf_sess.h"

#define MIC_IB_PAD 2
#define MIC_IN_PAD 3
#define MIC_EN_PAD 15

#define DMA_PCM_CHAN   DMA_CH0

int16_t pcm_buff0[PCM_LEN];
int16_t pcm_buff1[PCM_LEN];

uint8_t  adpcm_buff[ADPCM_LEN] = {0};

bool alt_selt = false;

struct adpcm_state state;

void uartTxSend(const uint8_t *data, uint16_t len)
{
    while(len--)
    {
        uart_putc(0, *data++);
    }
}

void micInit(void)
{
    dma_init();
        
    iom_ctrl(MIC_IB_PAD, 0);
    iom_ctrl(MIC_IN_PAD, IOM_ANALOG);   // 5 
    
    iom_ctrl(MIC_EN_PAD, IOM_PULLUP | IOM_INPUT);
    GPIO_DIR_CLR(GPIO15);
    
    adc_mic_init();
       
    // DMA Conf: direct Init
    SADC->CTRL.SADC_DMAC_EN = 0;      
    
    DMA_SADC_INIT(DMA_PCM_CHAN);
    DMA_SADC_PCM_CONF(DMA_PCM_CHAN, pcm_buff0, PCM_LEN, TRANS_PER_RD(CCM_PING_PONG, PCM_LEN, IN_HALF, IN_HALF) | DMA_TRANS_NEXTUB_BIT); 
    DMA_SADC_PCM_CONF(DMA_PCM_CHAN | DMA_CH_ALT, pcm_buff1, PCM_LEN, TRANS_PER_RD(CCM_PING_PONG, PCM_LEN, IN_HALF, IN_HALF) | DMA_TRANS_NEXTUB_BIT); 

    
    SADC->CTRL.SADC_DMAC_EN = 1;
    
    SADC->CH_CTRL.SADC_CH_SET0  = 4;
 
    // clear last flag.
    SADC->STCTRL.SADC_AUX_FLG_CLR = 1;
        
    // start conversion.   
    SADC->CTRL.SADC_SOC = 1; 

    state.index = 0;
    state.valprev = 0;
}

#if  (MODE_SELECT)
bool pcmPut(uint32_t *addr)
{
    // primary or alternate transfer done
    if (dma_chnl_done(DMA_PCM_CHAN))
    {   
        if (alt_selt)  // 0x100
        {
            uartTxSend((uint8_t *)&pcm_buff0, PCM_LEN*2); 
        }       
        else
        {
            uartTxSend((uint8_t *)&pcm_buff1, PCM_LEN*2);       
        }
        
        dma_chnl_reload(DMA_PCM_CHAN);

        alt_selt++;
    }
}
#else
void adpcmPut(void)
{
    // primary or alternate transfer done
    if (dma_chnl_done(DMA_PCM_CHAN))
    {   
        if (alt_selt)  // 0x100
        {
            adpcm_coder((short*)pcm_buff0, (char *)adpcm_buff, PCM_LEN, &state); 
        }       
        else
        {
            adpcm_coder((short*)pcm_buff1, (char *)adpcm_buff, PCM_LEN, &state);        
        }
        
//        uartTxSend((uint8_t *)&adpcm_buff, ADPCM_LEN);  
        sess_txd_send(app_env.curidx, ADPCM_LEN, (uint8_t *)&adpcm_buff);
        
        dma_chnl_reload(DMA_PCM_CHAN);        

        alt_selt++;
    }   
    
    if(GPIO_PIN_GET() & GPIO15)
    {
        if (SADC->CTRL.SADC_DMAC_EN)
            // close conversion.   
            SADC->CTRL.SADC_DMAC_EN = 0;     
    }
    else
    {    
        if (!SADC->CTRL.SADC_DMAC_EN)
            // start conversion.   
            SADC->CTRL.SADC_DMAC_EN = 1;        
    }        
}
#endif
